package modelo.tareas;

import java.util.Date;
import java.util.List;

import modelo.exception.NoPuedeIniciarException;
import modelo.exception.SameStateException;
import modelo.exception.StatusChangeException;

/**
 * @author Cristian
 *
 */

public class TareaCompuesta extends Tarea {
	
	// Variables  *********************************************************** //

	private List<Tarea> tareasQueComponen; 
	
	//Constructor *********************************************************** //

	public TareaCompuesta(String nom, int impo, String finalizacionEstimada, int estimacion, List<Tarea> tareas) {
		super(nom, impo,finalizacionEstimada,estimacion);
		this.tareasQueComponen = tareas;
	}
	
	public TareaCompuesta(String nom, int impo, String finalizacionEstimada, int estimacion,Tarea predecesor, List<Tarea> tareas) {
		super(nom, impo,finalizacionEstimada, estimacion, predecesor);
		this.tareasQueComponen = tareas;
	}

	//GET&SET     *********************************************************** //

	public List<Tarea> getTareas() {
		return tareasQueComponen;
	}

	public void setTareasQueComponen(List<Tarea> tareasQueComponen) {
		this.tareasQueComponen = tareasQueComponen;
	}


	//Metodos     *********************************************************** //
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime
				* result
				+ ((tareasQueComponen == null) ? 0 : tareasQueComponen
						.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		TareaCompuesta other = (TareaCompuesta) obj;
		if (tareasQueComponen == null) {
			if (other.tareasQueComponen != null)
				return false;
		} else if (!tareasQueComponen.equals(other.tareasQueComponen))
			return false;
		return true;
	}
	
	
	/**
	 * Se cambia el estado a estado iniciada.
	 * @throws StatusChangeException 
	 * @throws SameStateException 
	 * @throws NoPuedeIniciarException 
	 * @throws NoPuedeIniciarException 
	 */
	public void iniciarTarea() throws SameStateException, StatusChangeException, NoPuedeIniciarException {
		
		if(this.puedeIniciar(this)){
			for(Tarea t : this.getTareas()){
				t.iniciarTarea();
			}
		
			this.setEstado(this.estado.cambiarAIniciado());
		}		
		
	}

	/**
	 * Se cambia el estado a estado iniciado llamando al metodo iniciarTarea().
	 * Ya que depende la reapertura de sus predecesoras.
	 * @throws StatusChangeException 
	 * @throws SameStateException 
	 * @throws NoPuedeIniciarException 
	 */
	public String reabrirTarea(String nota) throws SameStateException, StatusChangeException, NoPuedeIniciarException {
		this.iniciarTarea();
		return nota;
	}

	/**
	 * Se cambia el estado a estado Finalizado.
	 * @throws StatusChangeException 
	 * @throws SameStateException 
	 */
	public void finalizarTarea() throws SameStateException, StatusChangeException {
		int tiempoRealizado = 0; 
		for(Tarea t : this.getTareas()){
			t.finalizarTarea();
			tiempoRealizado += t.getDuracion();
		}
		
		this.setEstado(this.getEstado().cambiarAFinalizado());
		Date tiempoFinalizado = new Date();
			
		this.fechaFinalizacion = tiempoFinalizado;
		this.duracion += tiempoDeRealizacion(this.realizacion, tiempoFinalizado)+ tiempoRealizado ;
			
	}
	
	/**
	 * Se cambia el estado a estado pausada.
	 * @throws StatusChangeException 
	 * @throws SameStateException 
	 */
	public void pausarTarea() throws SameStateException, StatusChangeException {
		
		this.setEstado(this.getEstado().cambiarAPausado());
		
		int tiempoRealizado = 0;
		for(Tarea t : this.getTareas()){
			t.pausarTarea();
			tiempoRealizado += t.getDuracion();
		}
		
		Date tiempoPausado = new Date();
		this.duracion += tiempoDeRealizacion(this.realizacion, tiempoPausado) + tiempoRealizado;
			
	}
	
	/**
	 * Se cambia el estado a estado cerrada.
	 * @throws StatusChangeException 
	 * @throws SameStateException 
	 */
	public void cerrarTarea() throws SameStateException, StatusChangeException {

		this.setEstado(this.getEstado().cambiarACerrado());
		if(this.realizacion == null){
			this.duracion = 0;
		}else{
			Date tiempoPausado = new Date();
			this.duracion += tiempoDeRealizacion(this.realizacion, tiempoPausado);}
		
		int tiempoRealizado = 0;
		for(Tarea t : this.getTareas()){
			t.cerrarTarea();
			tiempoRealizado += t.getDuracion();
		}
			
	}
	
	/**
	 * Se cambia el estado a estado enTrabajo.
	 * @throws StatusChangeException 
	 * @throws SameStateException 
	 */
	public void trabajarTarea() throws SameStateException, StatusChangeException {
		for(Tarea t : this.getTareas()){
			t.trabajarTarea();
		}
		this.setEstado(this.getEstado().cambiarAEnTrabajo());
		this.realizacion = new Date();
			
	}

	public int porcentajeDeRealizacion(){
		int porcentaje = 0;
		int cantTareas = 0;
		for(Tarea t : this.getTareas()){
			porcentaje += t.porcentajeDeRealizacion();
			cantTareas += 1;
		}
		return ((porcentaje +((this.duracion * 100) / this.estimacion))/(cantTareas+1));
	}
	
	public String toString () {
		return "Tarea Compuesta"; 
	}

}
